/*******************************************************************
 *
 * Copyright (C), 2021-2022, LS, All rights reserved.
 *
 * Author      : 
 * Create Time : 2020-12-15
 * Version     : v0.1
 * Description : 
 *******************************************************************/
 
/*----------------------------Head file----------------------------*/
#include "string.h"
#include "osal_app.h"
#include "bsp_hw_config.h"
#include "ls_ble_adpter.h"
#include "ls_ble_file_api.h"
#include "ls_ble_sdk_config.h"
#include "ls_ble_file_ota_api.h"
#include "ls_ble_file_protocol.h"

#include "app_global_data.h"

#if (LS_BLE_FILE_SVC_ENABLE)

#define BLE_FILE_API_LOG_EN  1
#if BLE_FILE_API_LOG_EN
#include "ls_ble_log.h"
#define TAG                             "ble_file"
#define BLE_FILE_API_LOG(level, ...)    LS_BLE_LOG_PRINT(level, TAG, __VA_ARGS__)
#else
#define BLE_FILE_API_LOG(...)
#endif

/*----------------------------macro file---------------------------*/
#define ONE_CHAR_BYTE_NUM       32

#define file_flash_erase_sector(addr)    ls_ble_adpter_flash_erase_sector(addr)
#define file_flash_write				 ls_ble_adpter_flash_write
#define file_flash_read                  ls_ble_adpter_flash_read

/*----------------------------type define--------------------------*/

/*----------------------------var define---------------------------*/							
static file_trans_t file_trans;
static bool trans_rsp_en = false;

/*-------------------------func declaration------------------------*/
extern void enter_ota_mode(void);
extern void exit_ota_mode(void);
extern void ota_done(void);

static void ls_ble_file_cmd_rx_payload_handle(uint8_t cmd, uint8_t *payload, uint16_t payload_len);
static void ls_ble_file_rx_file_data_handle(uint8_t *file_data, uint16_t data_len);

/*-----------------------------------------------------------------*/

void ls_ble_file_callback(ls_ble_file_cb_evt_param_t* param)
{
    switch(param->evt)
    {
        case LS_BLE_FILE_CB_EVT_DISCONNECT: {
            memset(&file_trans, 0, sizeof(file_trans));
            trans_rsp_en = false;
            exit_ota_mode();
        } break;
        
        case LS_BLE_FILE_CB_EVT_NTF_ENABLE: {
            LS_BLE_LOG_RAW_INFO("LS_BLE_FILE_CB_EVT_NTF_ENABLE\n");
        } break;
        
        case LS_BLE_FILE_CB_EVT_NTF_DISABLE: {
            LS_BLE_LOG_RAW_INFO("LS_BLE_FILE_CB_EVT_NTF_DISABLE\n");
        } break;
        
        /*case FILE_EVT_NOTIFICATION_COMPLETE: {
            
        } break;*/
        
        case LS_BLE_FILE_CB_EVT_RX_CMD_PAYLOAD: {
            ls_ble_file_cmd_rx_payload_handle(param->cmd, param->p_data, param->len);
        } break;
        
        case LS_BLE_FILE_CB_EVT_RX_FILE_DATA: {
            ls_ble_file_rx_file_data_handle(param->p_data, param->len);
        } break;
        
        default:
            break;
    }
}

void ls_ble_file_cmd_rx_payload_handle(uint8_t cmd, uint8_t *payload, uint16_t payload_len)
{
    /*LS_BLE_LOG_RAW_INFO("file rx Data:");
    for(int i=0;i<payload_len;i++) {
        LS_BLE_LOG_RAW_INFO("%x, ", payload[i]);
    }
    LS_BLE_LOG_RAW_INFO("\n");*/
    
    switch(cmd)
    {
        case FILE_CMD_TRANS_RSP_EN: {
            uint8_t err_code = 0;
            if(0 == payload[0]) {
                trans_rsp_en = false;
                file_upload_msg(FILE_CMD_TRANS_RSP_EN, &err_code, 1);  //Response
            }
            else if(1 == payload[0]) {
                trans_rsp_en = true;
                file_upload_msg(FILE_CMD_TRANS_RSP_EN, &err_code, 1);  //Response
            }
            
            LS_BLE_LOG_RAW_INFO("FILE_CMD_TRANS_RSP_EN: %d.\n", trans_rsp_en);
        } break;
        
        case FILE_CMD_OTA_INFO: {
            memset(&file_trans, 0, sizeof(file_trans));
            uint8_t err_code = ls_ble_file_set_ota_info(payload, payload_len, &file_trans);
            LS_BLE_LOG_RAW_INFO("err_code: %d.\n", err_code);
            file_upload_msg(FILE_CMD_OTA_INFO, &err_code, 1);  //Response
            enter_ota_mode();
        } break;
        
        case FILE_CMD_TRANS_DONE: {
            uint8_t err_code = 0;
            LS_BLE_LOG_RAW_INFO("FILE_CMD_TRANS_DONE.\n");
            if(payload[0] != file_trans.file_type) {
                err_code = FILE_DONE_CONTENT_ERR;
                LS_BLE_LOG_RAW_INFO("FILE_DONE_CONTENT_ERR.\n");
                file_upload_msg(FILE_CMD_TRANS_DONE, &err_code, 1);  //Response
                return;
            }
            
            if(FILE_TYPE_OTA == file_trans.file_type) {
                err_code = ls_ble_file_ota_trans_done_handle(&file_trans);
                LS_BLE_LOG_RAW_INFO("err_code: %d\n", err_code);
                if(0 == err_code) {
                    ota_done();
                    app_delay_reset(false);
                }
            }
            else {
                err_code = FILE_DONE_CONTENT_ERR;
            }
            file_upload_msg(FILE_CMD_TRANS_DONE, &err_code, 1);  //Response
            if(0 != err_code) {
                exit_ota_mode();
            }
        } break;

        default:
            break;
        //unknown command
    }
}


void ls_ble_file_rx_file_data_handle(uint8_t *file_data, uint16_t data_len)
{
    if(false == file_trans.running)
        return;

    if(true == ls_ble_file_ota_rx_raw_data_handle(file_data, data_len, &file_trans)) {
        if(true == trans_rsp_en) {
            file_upload_msg(FILE_CMD_RECV_DATA_LEN, (uint8_t*)&file_trans.offset, 4);
        }
    }
}

#endif
